@import "utilities";

//@descrip: css属性mixin，单一或几种相近css属性的混合，主要用于盒模型

//= 浮动，用于解决ie6双倍边距bug
//= @param: $value:left, right;
//= @param: $hack:是否需要hack;

@mixin float($value: left, $hack: true) {
  float: $value;

  @if $value != none and fix(6) and $hack {
    _display: inline;
  }
}

//= 清除浮动, 包括clearfix
//= @param: $way:both, left, right, fix, dom;

@mixin clear($way: $default-clear) {
  @if $way == fix {
    @if fix(7) {
      *zoom: 1;
    }

    &:after {
      display: block;
      clear: both;
      visibility: hidden;
      content: "\0020";

      @if fix(7) {
        height: 0;
        overflow: hidden;
      }
    }
  }

  @else if $way == dom {
    clear: both;

    @include height(0);
  }

  @else {
    clear: $way;
  }
}

//= 设置显示属性
@mixin display($value: block, $hack: true) {
  @if typeof($value) == list {
    $hack: nth($value, 2);
    $value: nth($value, 1);
  }

  @if $value == inb {
    $value: inline-block;
  }

  display: $value;

  @if $value == inline-block {
    @if fix(7) and $hack {
      *display: inline;
      *zoom: 1;
    }
  }

  @else {
    @if $value == box {
      @if fix(webkit) {
        display: -webkit-box;
      }

      @if fix(ff) {
        display: -moz-box;
      }
    }
  }
}

//= 配合display:box设置box-flex
@mixin box-flex($value: 1, $hack: true) {
  @if fix(webkit) {
    -webkit-box-flex: $value;
  }

  @if fix(ff) {
    -moz-box-flex: $value;
  }

  @if fix(10) and $hack {
    -ms-box-flex: $value;
  }

  flex: $value;
}

//= 生成背景或背景色或背景位置
//= @param: $value:color值时生成背景色，数值或位置信息时生成背景位置，其余生成完整的background;

@mixin background($value) {
  @if typeof($value) == color {
    background-color: $value;
  }

  @else if typeof($value) == list and ((typeof(n($value, 1)) == number or index($default-direction, n($value, 1))) and (typeof(n($value, 2)) == number or index($default-direction, n($value, 2)))) {
    background-position: $value;
  }

  @else if chk($value) {
    background: $value;
  }
}

//= 设置透明度
//= @param: $value:小于1的值;

@mixin opacity($value: $default-opacity) {
  opacity: $value;

  @if fix(8) {
    filter: alpha(opacity = floor($value * 100));
  }
}

//= overflow
//= @param: $axis:x/y/all;
//= @param: $way:overflow's value;

@mixin overflow($axis: all, $way: $default-overflow) {
  @if not index(x y, $axis) {
    @if index(hidden visible scroll auto inherit, $axis) {
      $way: $axis;
    }

    $axis: null;
  }

  #{splice(overflow $axis)}: $way;
}

//= 设置宽度
//= @param: $value:宽度值;
//= @param: $hack:是否hack/hack值;
//= @param: $type:hack的类型;

@mixin width($value: $default-box-size, $hack: false, $type: null) {
  @if typeof($value) == list {
    $type: n($value, 3);
    $hack: nth($value, 2);
    $value: nth($value, 1);
  }

  @include set-size(width, $value, $hack, $type);
}

//= 设置行高
//= @param: $value:行高值;
//= @param: $hack:是否hack;
//= @param: $type:hack的类型;

@mixin line-height($value: $default-line-height, $hack: false, $type: null) {
  @include set-size(line-height, $value, $hack, $type);
}

//= 设置高度
//= @param: $value:高度值;
//= @param: $line-height:行高值,为true时等于高度值;
//= @param: $hack:是否hack/hack值，$height小于默认字体大小时，如果此值为true，会用font-size修正ie6 bug;
//= @param: $hack-line:是否hack行高;
//= @param: $type:hack的类型;

@mixin height($value: $default-box-size, $line-height: true, $hack: true, $hack-line: false, $type: null) {
  $height: $value;
  $value: no-important($value);

  @if typeof($value) == list {
    @if nth($value, 2) != !important {
      $line-height: nth($value, 2);
      $height: nth($value, 1);
    }
  }

  $value: if(typeof($value) == number, $value, $height);

  @include set-size(height, $height, $hack, $type);

  $line: false;

  @if $line-height {
    $line-height: if($line-height == true, $height, $line-height);
    $line: true;

    @include line-height($line-height, $hack-line, $type);
  }

  @if fix(pc) and $hack == true and typeof($value) == number {
    @if unit($value) == px or $value == 0 {
      @if $value < $default-font-size-base {
        @if not $line {
          line-height: $height;
        }

        font-size: $value * 0.875;
      }
    }

    @else if unit($value) == em {
      @if $value < 1em {
        @if not $line {
          line-height: $height;
        }

        font-size: $value * 0.875;
      }
    }
  }
}

//= all borders，参数多用途，功能强大
//= @param: $color:默认边框色，为长度值则相当于$width，为default则生成默认边框样式，为string则相当于$style，为0/none时指无边框，结合$width的方位值可以单独生成某条边的边框属性，为空或false单独生成style及width，甚至可以传入多组颜色，或 2px dashed #333 及(2px dotted #111,3px dashed #222,4px solid #333)组合值;
//= @param: $width:默认边框宽1px;为(left/right/top/bottom)任一值或多个值，则单独生成某条边的样式;为空或false单独生成style及color;为no-xxx并且$color为列表值时就不生成某条边框样式;
//= @param: $style:默认边框样式solid;为空或false单独生成width和color;
//= @param: 三个参数均不传时生成默认的边框样式，同理传其中一个或两个参数时剩下的均为默认值;但是如果$color传两个值，就会分别单独生成对应的border属性。

@mixin border($color: $default-border-color, $width: $default-border-width, $style: $default-border-style) {
  @if chk($color) {
    @if typeof($color) == color {
      @if typeof($width) == number {
        @if typeof($style) == string {
          border: $width $style $color;
        }

        @else if not $style {
          @include border-width($width);
          @include border-color($color);
        }
      }

      @else if typeof($width) == string {
        @if index($default-direction, $width) {
          @include border-property($width, $default-border-width $default-border-style $color);
        }

        @else if index(no-top no-right no-bottom no-left, $width) {
          $color: border-value($color);

          @each $v in $default-direction {
            @if $width != unquote("no-#{$v}") {
              border-#{$v}: $color;
            }
          }
        }

        @else if $width == color {
          border-color: $color;
        }

        @else {
          border: $default-border-width $style $color;
        }
      }

      @else if typeof($width) == list {
        @each $v in $width {
          @if index($default-direction, $v) {
            @include border-property($v, $default-border-width $default-border-style $color);
          }
        }
      }

      @else if not $width {
        @include border-style($style);
        @include border-color($color);
      }
    }

    @else if typeof($color) == number and $color != 0 {
      @if typeof($width) == string and typeof($style) == color or typeof($width) == color and typeof($style) == string {
        border: border-value($color $width $style);
      }

      @else if index($default-direction, $width) {
        @include border-property($width, $color $default-border-style $default-border-color);
      }

      @else if typeof($width) == list {
        @each $v in $width {
          @if index($default-direction, $v) {
            @include border-property($v, $color $default-border-style $default-border-color);
          }
        }
      }

      @else {
        border: $color $style $default-border-color;
      }
    }

    @else if $color == 0 {
      $color: 0 none;

      @if index($default-direction, $width) {
        @include border-property($width, $color);
      }

      @else if typeof($width) == list {
        @each $v in $width {
          @if index($default-direction, $v) {
            @include border-property($v, $color);
          }
        }
      }

      @else {
        border: $color;
      }
    }

    @else if typeof($color) == string {
      $color: $color;

      @if index($default-direction, $width) {
        @include border-property($width, $default-border-width $color $default-border-color);
      }

      @else if typeof($width) == list {
        @each $v in $width {
          @if index($default-direction, $v) {
            @include border-property($v, $default-border-width $color $default-border-color);
          }
        }
      }

      @else if $color == default {
        border: $default-border-width $default-border-style $default-border-color;
      }

      @else if $color == none {
        border: 0 none;
      }

      @else {
        border: $width $color $default-border-color;
      }
    }

    @else if typeof($color) == list {
      $colors: null;
      $widths: null;
      $styles: null;

      @each $v in $color {
        @if typeof($v) == color {
          $colors: if($colors == null, $v, join(unquote($colors), $v, space));
        }

        @else if typeof($v) == number {
          $widths: if($widths == null, $v, join(unquote($widths), $v, space));
        }

        @else if typeof($v) == string {
          $styles: if($styles == null, $v, join(unquote($styles), $v, space));
        }
      }

      @if typeof($widths) == number and typeof($colors) == color and typeof($styles) == string {
        $len: length($widths);

        @if $len > 1 {
          @for $i from 1 through 4 {
            $d: nth($default-direction, $i);
            $index: 5;

            @if $width != unquote("no-#{$d}") {
              @if $i <= $len {
                @if $i > $index {
                  $i: $i - 1;
                }

                @include border-property($d, n($widths, $i) n($styles, $i) n($colors, $i));
              }
            }

            @else {
              $index: $i;
            }
          }
        }

        @else {
          @if index($default-direction, $width) {
            border-#{$width}: $color;
          }

          @else if typeof($width) == list {
            @each $v in $width {
              @if index($default-direction, $v) {
                border-#{$v}: $color;
              }
            }
          }

          @else if index(no-top no-right no-bottom no-left, $width) {
            @each $v in $default-direction {
              @if $width != "no-#{$v}" {
                border-#{$v}: $color;
              }
            }
          }

          @else {
            border: $color;
          }
        }
      }

      @else {
        @if $widths {
          @include border-width($widths);
        }

        @if $styles {
          @include border-style($styles);
        }

        @if $colors {
          @include border-color($colors);
        }
      }
    }
  }

  @else if $color != false {
    @include border-style($style);
    @include border-width($width);
  }
}

//= 设置顶边框值
//= @param: $value:传值多样性，可以只传一个，两个，或三个属性，默认会把其余属性补齐;
//= @param: $merge:是否缩写还是单独设置各个属性，默认true;

@mixin border-top($value: $default-border, $merge: true) {
  @include border-property(top, $value, $merge);
}

//= 设置右边框值，参数同上
@mixin border-right($value: $default-border, $merge: true) {
  @include border-property(right, $value, $merge);
}

//= 设置底边框值，参数同上
@mixin border-bottom($value: $default-border, $merge: true) {
  @include border-property(bottom, $value, $merge);
}

//= 设置左边框值，参数同上
@mixin border-left($value: $default-border, $merge: true) {
  @include border-property(left, $value, $merge);
}

//= 设置边框宽度
//= @param: $value:默认border宽度;
//= @param: $merge:单独设置各边值还是缩写，可以是每条边或组合，分别生成对应边的border宽度;

@mixin border-width($value: $default-border-width, $merge: true) {
  @include border-property(width, $value, $merge);
}

//= 设置边框样式
//= @param: $value:默认border样式;
//= @param: $merge:单独设置各边值还是缩写，可以是每条边或组合，分别生成对应边的border样式;

@mixin border-style($value: $default-border-style, $merge: true) {
  @include border-property(style, $value, $merge);
}

//= 设置边框颜色
//= @param: $value:默认border颜色;
//= @param: $merge:单独设置各边值还是缩写，可以是每条边或组合，分别生成对应边的border颜色;

@mixin border-color($value: $default-border-color, $merge: true) {
  @include border-property(color, $value, $merge);
}

//= 设置padding，可分别设置每面的padding及hack。
//= @param: $value:属性值的集合，可包含$merge/$hack;
//= @param: $merge:是否合并各边距;
//= @param: $hack:是否有hack及hack值;

@mixin padding($value: $default-padding, $merge: true, $hack: false) {
  $m: split-values($value, 1);
  $h: split-values($value, 1, _ _);

  @if $h != null {
    $hack: $h;
  }

  @if chk($m) or $m == false {
    $value: split-values($value, 0);
    $merge: $m;
    $vl: length($value);
    $ml: length($merge);

    @if $vl < $ml {
      @for $i from 1 through $ml {
        @if $i > $vl {
          $value: join($value, nth($value, $vl), comma);
        }
      }
    }
  }

  @include set-patch(padding, $value, $merge, $hack);
}

//= 设置margin，可分别设置每面的margin及hack。
//= @param: $value:属性值的集合，可包含$merge/$hack;
//= @param: $merge:是否合并各边距;
//= @param: $hack:是否有hack及hack值;

@mixin margin($value: $default-margin, $merge: true, $hack: false) {
  $m: split-values($value, 1);
  $h: split-values($value, 1, _ _);

  @if $h != null {
    $hack: $h;
  }

  @if chk($m) or $m == false {
    $value: split-values($value, 0);
    $merge: $m;
    $vl: length($value);
    $ml: length($merge);

    @if $vl < $ml {
      @for $i from 1 through $ml {
        @if $i > $vl {
          $value: join($value, nth($value, $vl), comma);
        }
      }
    }
  }

  @include set-patch(margin, $value, $merge, $hack);
}

//= position属性：position,z-index,left,top,right,bottom
//= @param: $pos:可以为集合，包含$direct/$value/z-index;
//= @param: $direct:z-index/left/top/right/bottom其中之一或组合，还可以包含zero/lt/rb/lb/rt/cc/tc/lc/rc/bc等值分别类似9点定位的各顶点;
//= @param: $value:各属性值或组合;
//= @param: $z/$l/$t/$r/$b分别设置z-index/left/top/right/bottom属性;

@mixin position($pos: $default-position, $direct: false, $value: $default-position, $z: false, $l: false, $t: false, $r: false, $b: false) {
  @if $pos {
    @if typeof($pos) == list {
      @if typeof(nth($pos, 2)) == number {
        $l: nth($pos, 2);

        @if typeof(n($pos, 3, false)) == number {
          $t: n($pos, 3, false);
        }

        @if typeof(n($pos, 4, false)) == number {
          $z: n($pos, 4, false);
        }
      }

      @else {
        $z: n($pos, 4, false);
        $value: n($pos, 3, false);
        $direct: nth($pos, 2);
      }

      $pos: nth($pos, 1);
    }

    position: $pos;
  }

  @if typeof($direct) == list {
    $i: 1;

    @each $v in $direct {
      @if n($value, $i, false) {
        #{$v}: n($value, $i);
      }

      @else if n($value, $i, false) != false {
        #{$v}: 0;
      }

      $i: $i + 1;
    }
  }

  @else if $direct == 0 or $direct == lt or $direct == tl {
    top: 0;
    left: 0;
  }

  @else if $direct == rb or $direct == br {
    right: 0;
    bottom: 0;
  }

  @else if $direct == lb or $direct == bl {
    bottom: 0;
    left: 0;
  }

  @else if $direct == rt or $direct == tr {
    top: 0;
    right: 0;
  }

  @else if $direct == center or $direct == cc {
    top: 50%;
    left: 50%;
  }

  @else if $direct == tc or $direct == ct {
    top: 0;
    left: 50%;
  }

  @else if $direct == lc or $direct == cl {
    top: 50%;
    left: 0;
  }

  @else if $direct == rc or $direct == cr {
    top: 50%;
    right: 0;
  }

  @else if $direct == bc or $direct == cb {
    bottom: 0;
    left: 50%;
  }

  @else if ($direct == z or $direct == z-index) and $value {
    z-index: $value;
  }

  @else if $direct {
    #{$direct}: $value;
  }

  @else {
    @if $l {
      left: $l;
    }

    @if $t {
      top: $t;
    }

    @if $r {
      right: $r;
    }

    @if $b {
      bottom: $b;
    }
  }

  @if chk($z) and ($direct != z and $direct != z-index) {
    @if typeof($direct) == list {
      @if not index($direct, z) and not index($direct, z-index) {
        z-index: $z;
      }
    }

    @else {
      z-index: $z;
    }
  }
}

//= position为 absolute 时的其余属性，对应position(absolute)的快捷方式，比如可以这样使用@include absolute(lt)或@include absolute(left top, 5px 10px)可以理解为绝对定位到左上角，偏移量为左5上10，下同
@mixin absolute($direct: false, $value: $default-position, $z: false, $l: false, $t: false, $r: false, $b: false) {
  @include position(absolute, $direct, $value, $z, $l, $t, $r, $b);
}

//= position为 relative 时的其余属性，对应position(relative)的快捷方式
@mixin relative($direct: false, $value: $default-position, $z: false, $l: false, $t: false, $r: false, $b: false) {
  @include position(relative, $direct, $value, $z, $l, $t, $r, $b);
}

//= position为 fixed 时的其余属性，对应position(fixed)的快捷方式
@mixin fixed($direct: false, $value: $default-position, $z: false, $l: false, $t: false, $r: false, $b: false) {
  @include position(fixed, $direct, $value, $z, $l, $t, $r, $b);
}
